package com.sasis.webapp.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.acegisecurity.Authentication;
import org.acegisecurity.context.SecurityContextHolder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.sasis.model.BasePermission;
import com.sasis.model.Function;
import com.sasis.model.User;
import com.sasis.service.FunctionService;
import com.sasis.service.PermissionService;

public class PermissionFilter implements Filter {
	
	private static final Log log = LogFactory.getLog(PermissionFilter.class);
	
	private String permissionUrl;
	
	private FilterConfig filterConfig;
	 
	public void init(FilterConfig filterConfig) throws ServletException {
		this.filterConfig = filterConfig;
		permissionUrl = filterConfig.getInitParameter("url");
		if (permissionUrl != null) {
			permissionUrl = permissionUrl.trim();
		}
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
		try {
			HttpServletRequest httpRequest = (HttpServletRequest)request;
			HttpServletResponse httpResponse = (HttpServletResponse)response;
			log.debug("PermissionFilter:" + httpRequest.getRequestURI());
			HttpSession session = httpRequest.getSession();
			if (session != null) {
				Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
				if (authentication != null) {
					Object obj = authentication.getPrincipal();
					if (obj instanceof User) {
						User user = (User)obj;
						String uri = httpRequest.getRequestURI();
						String context = httpRequest.getContextPath();
						if (context == null) context = "";
						uri = uri.substring(context.length() + 1);
						FunctionService functionService = (FunctionService)WebApplicationContextUtils.getRequiredWebApplicationContext(filterConfig.getServletContext()).getBean("functionService");
						Function function = functionService.loadByUrl(uri);
						if (function != null) {
							PermissionService permissionService = (PermissionService)WebApplicationContextUtils.getRequiredWebApplicationContext(filterConfig.getServletContext()).getBean("permissionService");
							if (! permissionService.validate(new BasePermission(user, function, true))) {
								if (log.isDebugEnabled()) {
									log.debug("forbid user (id:" + user.getUsername() + ") visit " + uri);
								}
								if (permissionUrl == null || permissionUrl.length() == 0) {
									httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
								} else {
									httpResponse.sendRedirect(permissionUrl);
								}
								return ;
							}
						}
					}
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		filterChain.doFilter(request, response);
	}

	public void destroy() {
		
	}

}
